package com.huiying.aspect;


import com.huiying.annotation.AutoFile;
import com.huiying.constant.AutoFillConstant;
import com.huiying.context.BaseContext;
import com.huiying.utils.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @Author: lsh
 * @Date: 2024/10/15/16:29
 * @Description: 自定义切面类,用于公共字段的自动注入
 */

@Aspect
@Slf4j
@Component
public class AutoFileAspect {

    //切面表达式，扫描mapper层下那些类使用了注解来自动注入公共字段
    @Pointcut("execution(* com.huiying.mapper.*.*(..)) && @annotation(com.huiying.annotation.AutoFile)")
    public void autoFilePointCut(){}

    //在加入注解的类执行前自动填充字段
    @Before("autoFilePointCut()")
    public void autoFile(JoinPoint joinPoint){
        log.info("开始字段的自动注入");

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFile autoFile = signature.getMethod().getAnnotation(AutoFile.class);

        OperationType value = autoFile.value();

        Object[] args = joinPoint.getArgs();
        Object arg = args[0];

        LocalDateTime now = LocalDateTime.now();
        Long id = BaseContext.getCurrentId();

        if (value == OperationType.INSERT){
            try {
                Method setCreateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);

                setCreateTime.invoke(arg,now);
                setUpdateTime.invoke(arg,now);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else if (value == OperationType.UPDATE) {
            try {
                Method setUpdateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);

                setUpdateTime.invoke(arg,now);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
    }
}
